#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <PubSubClient.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#include <ArduinoJson.h>

// MAX485控制引脚定义
#define MAX485_RE_DE 5    // RE/DE控制引脚 → GPIO5(D1)
#define MAX485_DI 1       // DI数据输入引脚 → GPIO1(D10)
#define MAX485_RO 3       // RO数据输出引脚 → GPIO3(D9)
// 新增串口读取超时控制
#define SERIAL_READ_TIMEOUT 1000  // 毫秒,1s
const unsigned long sendInterval = 5000; // 发送指令到485接口的间隔（5秒）
const unsigned long mqttReconnectInterval = 10000; // MQTT重连间隔（10秒）

// LCD配置 - 0.96英寸OLED (SSD1306驱动)
#define SDA_PIN 14  // D6
#define SCL_PIN 12  // D5
// OLED定义（128x64，I2C接口）
#define OLED_RESET -1
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
SoftwareSerial max485Serial(MAX485_RO, MAX485_DI);

// 配置结构体
struct BMSConfig {
  char ssid[32];
  char password[64];
  char mqtt_server[40];
  int mqtt_port;
  char mqtt_topic[64];
  char command[64];
  bool configReady;
};

BMSConfig bmsConfig;
const int configVersion = 1; // 用于配置版本控制

WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server(80);
unsigned long lastSendTime = 0;
unsigned long lastMQTTConnectAttempt = 0;
bool apModeActive = false;  // 新增标志，指示是否处于AP模式
bool serverStarted = false; // 新增标志，指示Web服务器是否已启动
bool mqttConnected = false; // 新增标志，指示MQTT连接状态

// 调试信息缓冲区
#define DEBUG_BUFFER_SIZE 10
String debugMessages[DEBUG_BUFFER_SIZE];
int debugIndex = 0;
String lastSentCommand = "";
String lastReceivedResponse = "";

// 初始化EEPROM
void initEEPROM() {
  EEPROM.begin(512);
  
  // 读取配置
  EEPROM.get(0, bmsConfig);
  
  // 检查配置是否有效
  bool configValid = true;
  
  // 验证字符串字段是否包含有效内容
  if (!validateString(bmsConfig.ssid, sizeof(bmsConfig.ssid))) configValid = false;
  if (!validateString(bmsConfig.password, sizeof(bmsConfig.password))) configValid = false;
  if (!validateString(bmsConfig.mqtt_server, sizeof(bmsConfig.mqtt_server))) configValid = false;
  if (!validateString(bmsConfig.mqtt_topic, sizeof(bmsConfig.mqtt_topic))) configValid = false;
  if (!validateString(bmsConfig.command, sizeof(bmsConfig.command))) configValid = false;
  
  // 验证配置版本
  if (bmsConfig.configReady != configVersion) {
    configValid = false;
  }
  
  // 打印调试信息
  Serial.print("Config validation result: ");
  Serial.println(configValid ? "VALID" : "INVALID");
  
  if (!configValid) {
    // 配置无效或未初始化，设置默认值
    Serial.println("Initializing default configuration...");
    
    // 先清空所有字符串字段
    memset(bmsConfig.ssid, 0, sizeof(bmsConfig.ssid));
    memset(bmsConfig.password, 0, sizeof(bmsConfig.password));
    memset(bmsConfig.mqtt_server, 0, sizeof(bmsConfig.mqtt_server));
    memset(bmsConfig.mqtt_topic, 0, sizeof(bmsConfig.mqtt_topic));
    memset(bmsConfig.command, 0, sizeof(bmsConfig.command));
    
    // 设置默认值
    strcpy(bmsConfig.ssid, "hgsy");
    strcpy(bmsConfig.password, "hg111111");
    strcpy(bmsConfig.mqtt_server, "192.168.1.222");
    bmsConfig.mqtt_port = 1883;
    strcpy(bmsConfig.mqtt_topic, "bms48200/data");
    strcpy(bmsConfig.command, "~200046F2E00201FD24\r");
    bmsConfig.configReady = configVersion;
    
    // 保存默认配置
    saveConfig();
  } else {
    Serial.println("Loading saved configuration...");
    printConfig();
  }
}

// 生成随机ClientID
String generateRandomClientID() {
  String clientID = "ESP8266-BMS-";
  clientID += String(random(1000, 9999));
  clientID += "-";
  clientID += String(millis() % 10000);
  return clientID;
}

// 验证字符串是否有效
bool validateString(char* str, size_t maxLength) {
  // 检查字符串长度是否合理
  size_t len = strlen(str);
  
  // 打印调试信息
  Serial.print("Validating string: ");
  Serial.print(str);
  Serial.print(", length: ");
  Serial.print(len);
  Serial.print(", max length: ");
  Serial.println(maxLength);
  
  // 检查长度是否为0或超过最大长度
  if (len == 0 || len >= maxLength - 1) {
    Serial.println("-> Invalid: length check failed");
    return false;
  }
  
  // 检查字符串中是否包含非法字符
  for (size_t i = 0; i < len; i++) {
    if (!isPrintable(str[i])) {
      Serial.print("-> Invalid: non-printable character at position ");
      Serial.println(i);
      return false;
    }
  }
  
  return true;
}

// 打印配置信息（用于调试）
void printConfig() {
  Serial.println("Current configuration:");
  Serial.print("  SSID: "); Serial.println(bmsConfig.ssid);
  Serial.print("  Password: "); Serial.println(bmsConfig.password);
  Serial.print("  MQTT Server: "); Serial.println(bmsConfig.mqtt_server);
  Serial.print("  MQTT Port: "); Serial.println(bmsConfig.mqtt_port);
  Serial.print("  MQTT Topic: "); Serial.println(bmsConfig.mqtt_topic);
  Serial.print("  Command: "); Serial.println(bmsConfig.command);
  Serial.print("  Config Version: "); Serial.println(bmsConfig.configReady);
}

// 保存配置到EEPROM
void saveConfig() {
  EEPROM.put(0, bmsConfig);
  EEPROM.commit();
  Serial.println("Configuration saved");
  addDebugMessage("Configuration saved");
}

// 添加调试信息
void addDebugMessage(String message) {
  debugMessages[debugIndex] = message;
  debugIndex = (debugIndex + 1) % DEBUG_BUFFER_SIZE;
}

// 扫描可用的WiFi网络
void scanWiFiNetworks() {
  Serial.println("Scanning available WiFi networks...");
  addDebugMessage("Scanning WiFi networks");
  showLCD("Scanning WiFi...", 0, false);
  
  int n = WiFi.scanNetworks();
  Serial.println("Scan completed");
  addDebugMessage("WiFi scan completed: " + String(n) + " networks found");
  
  if (n == 0) {
    Serial.println("No networks found");
    showLCD("No networks found", 0, false);
    addDebugMessage("No WiFi networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    showLCD(String(n) + " networks", 0, false);
    
    for (int i = 0; i < n && i < 3; i++) {
      showLCD(WiFi.SSID(i) + " (" + String(WiFi.RSSI(i)) + ")", i, false);
      delay(1000);
    }
  }
}

// 连接WiFi
bool connectWiFi() {
  if (apModeActive) return false;
  
  const int maxAttempts = 5;
  int attempt = 0;
  
  while (attempt < maxAttempts) {
    Serial.print("WiFi Attempt ");
    Serial.print(attempt + 1);
    Serial.print("/");
    Serial.print(maxAttempts);
    Serial.print(": Connecting to ");
    Serial.println(bmsConfig.ssid);
    addDebugMessage("WiFi Attempt " + String(attempt + 1) + "/" + String(maxAttempts) + ": Connecting to " + String(bmsConfig.ssid));
    
    showLCD("WiFi Connecting...", 0, false);
    showLCD("Attempt " + String(attempt + 1) + "/" + String(maxAttempts), 1, false);
    
    WiFi.mode(WIFI_STA);
    WiFi.begin(bmsConfig.ssid, bmsConfig.password);
    
    int cycles = 0;
    while (WiFi.status() != WL_CONNECTED && cycles < 20) {
      delay(500);
      cycles++;
    }
    
    if (WiFi.status() == WL_CONNECTED) {
      // 等待获取IP地址
      Serial.println("WiFi connected, waiting for IP...");
      addDebugMessage("WiFi connected, waiting for IP");
      delay(1000);
      
      IPAddress ip = WiFi.localIP();
      if (ip[0] == 0) {
        Serial.println("IP address not properly assigned yet");
        showLCD("IP Not Assigned", 0, false);
        addDebugMessage("IP address not properly assigned yet");
        delay(2000);
        return false;
      }
      
      Serial.println("IP address: " + ip.toString());
      showLCD("WiFi Connected", 0, true);
      showLCD("IP: " + ip.toString(), 1, true);
      addDebugMessage("WiFi IP address: " + ip.toString());
      
      // 启动Web服务器
      if (!serverStarted) {
        setupServerRoutes();
        server.begin();
        serverStarted = true;
        Serial.println("Web server started on port 80");
        showLCD("Web Server: 80", 2, true);
        addDebugMessage("Web server started on port 80");
      }
      
      return true;
    } else {
      Serial.println("WiFi connection failed");
      showLCD("WiFi Failed", 0, false);
      showLCD("Retry in 5s", 1, false);
      addDebugMessage("WiFi connection failed, retrying in 5s");
      attempt++;
      delay(5000);
    }
  }
  
  scanWiFiNetworks();
  return false;
}

// 启动AP模式进行配置
void startAP() {
  WiFi.mode(WIFI_AP);
  WiFi.softAP("ESP8266 BMS Config", "12345678");
  apModeActive = true;
  
  Serial.println("AP mode started");
  IPAddress ip = WiFi.softAPIP();
  Serial.println("AP IP address: " + ip.toString());
  addDebugMessage("AP mode started, IP: " + ip.toString());
  
  showLCD("AP Mode Active", 0, false);
  showLCD("Connect to web", 1, false);
  showLCD("192.168.4.1", 2, false);
  
  // 启动Web服务器
  if (!serverStarted) {
    setupServerRoutes();
    server.begin();
    serverStarted = true;
    Serial.println("Web server started on port 80");
    addDebugMessage("Web server started on port 80");
  }
}

// 连接MQTT
bool connectMQTT() {
  if (apModeActive) return false;
  
  if (!WiFi.isConnected()) {
    Serial.println("WiFi not connected, cannot connect to MQTT");
    addDebugMessage("WiFi not connected, cannot connect to MQTT");
    return false;
  }
  
  Serial.print("Attempting MQTT connection to ");
  Serial.print(bmsConfig.mqtt_server);
  Serial.print(":");
  Serial.println(bmsConfig.mqtt_port);
  addDebugMessage("Attempting MQTT connection to " + String(bmsConfig.mqtt_server) + ":" + String(bmsConfig.mqtt_port));
  
  showLCD("MQTT Connecting...", 0, false);
  
  // 生成随机ClientID
  String clientID = generateRandomClientID();
  Serial.println("Using ClientID: " + clientID);
  addDebugMessage("Using MQTT ClientID: " + clientID);
  
  // 设置MQTT服务器和端口
  client.setServer(bmsConfig.mqtt_server, bmsConfig.mqtt_port);
  
  // 尝试连接
  if (client.connect(clientID.c_str())) {
    Serial.println("MQTT connected");
    mqttConnected = true;
    showLCD("MQTT Connected", 0, true);
    showLCD("ID: " + clientID.substring(0, 16), 1, true);
    addDebugMessage("MQTT connected successfully");
    return true;
  } else {
    Serial.print("MQTT connection failed, rc=");
    Serial.println(client.state());
    mqttConnected = false;
    showLCD("MQTT Failed", 0, false);
    showLCD("State: " + String(client.state()), 1, false);
    addDebugMessage("MQTT connection failed, rc=" + String(client.state()));
    return false;
  }
}

// 获取MQTT状态文本
String getMQTTStatusText() {
  if (!mqttConnected) return "Disconnected";
  
  String status = "Connected";
  if (client.state() != 0) {
    status += " (State: " + String(client.state()) + ")";
  }
  return status;
}

// 设置Web服务器路由
void setupServerRoutes() {
  // 根路径 - 返回配置页面
  server.on("/", []() {
    String page = "<!DOCTYPE html><html><head>";
    page += "<meta charset=\"UTF-8\">";
    page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">";
    page += "<title>ESP8266 BMS Configuration</title>";
    page += "<style>";
    page += "body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f4f4f4; }";
    page += ".tab-container { margin-top: 20px; }";
    page += ".tabs { display: flex; border-bottom: 1px solid #ccc; }";
    page += ".tab { padding: 10px 15px; cursor: pointer; border: 1px solid #ccc; border-bottom: none; margin-right: -1px; background-color: #eee; }";
    page += ".tab.active { background-color: #fff; font-weight: bold; }";
    page += ".tab-content { padding: 20px; background-color: #fff; border: 1px solid #ccc; border-top: none; }";
    page += ".status-item { margin-bottom: 10px; }";
    page += ".debug-item { margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #eee; }";
    page += ".debug-timestamp { color: #888; font-size: 0.9em; }";
    page += ".form-group { margin-bottom: 15px; }";
    page += "label { display: block; margin-bottom: 5px; }";
    page += "input { width: 100%; padding: 8px; box-sizing: border-box; }";
    page += "button { padding: 10px 15px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }";
    page += "button:hover { background-color: #45a049; }";
    page += ".actions { margin-top: 20px; }";
    page += ".action-btn { display: inline-block; margin-right: 10px; margin-bottom: 10px; padding: 8px 15px; background-color: #f0f0f0; color: #333; text-decoration: none; border: 1px solid #ccc; border-radius: 4px; }";
    page += ".action-btn:hover { background-color: #e0e0e0; }";
    page += ".status-ok { color: green; }";
    page += ".status-error { color: red; }";
    page += ".refresh-indicator { float: right; font-size: 0.9em; color: #888; }";
    page += "</style>";
    page += "<script>";
    page += "function openTab(tabName) {";
    page += "  var i, tabcontent, tablinks;";
    page += "  tabcontent = document.getElementsByClassName(\"tab-content\");";
    page += "  for (i = 0; i < tabcontent.length; i++) {";
    page += "    tabcontent[i].style.display = \"none\";";
    page += "  }";
    page += "  tablinks = document.getElementsByClassName(\"tab\");";
    page += "  for (i = 0; i < tablinks.length; i++) {";
    page += "    tablinks[i].className = tablinks[i].className.replace(\" active\", \"\");";
    page += "  }";
    page += "  document.getElementById(tabName).style.display = \"block\";";
    page += "  document.getElementById(tabName + \"Tab\").className += \" active\";";
    page += "}";
    page += "function refreshStatus() {";
    page += "  document.getElementById('status-content').innerHTML = '<div style=\"text-align:center;\">Refreshing...</div>';";
    page += "  fetch('/status')";
    page += "    .then(response => response.text())";
    page += "    .then(data => {";
    page += "      document.getElementById('status-content').innerHTML = data;";
    page += "      setTimeout(refreshStatus, 20000);";
    page += "    })";
    page += "    .catch(error => {";
    page += "      document.getElementById('status-content').innerHTML = '<div class=\"status-error\">Failed to refresh status</div>';";
    page += "      setTimeout(refreshStatus, 20000);";
    page += "    });";
    page += "}";
    page += "document.addEventListener('DOMContentLoaded', function() {";
    page += "  openTab('status');";
    page += "  refreshStatus();";
    page += "});";
    page += "</script>";
    page += "</head><body>";
    page += "<h1>ESP8266 BMS Controller</h1>";
    
    page += "<div class=\"tab-container\">";
    page += "  <div class=\"tabs\">";
    page += "    <div id=\"statusTab\" class=\"tab\" onclick=\"openTab('status')\">Status</div>";
    page += "    <div id=\"configTab\" class=\"tab\" onclick=\"openTab('config')\">Configuration</div>";
    page += "  </div>";
    
    page += "  <div id=\"status\" class=\"tab-content\">";
    page += "    <div class=\"refresh-indicator\">Last updated: <span id=\"last-update\">" + String(millis() / 1000) + "</span>s</div>";
    page += "    <div id=\"status-content\">Loading status...</div>";
    page += "  </div>";
    
    page += "  <div id=\"config\" class=\"tab-content\">";
    page += "    <form action=\"/save\" method=\"post\">";
    
    page += "      <div class=\"form-group\">";
    page += "        <h2>WiFi Configuration</h2>";
    page += "        <label for=\"ssid\">SSID:</label>";
    page += "        <input type=\"text\" name=\"ssid\" value=\"" + String(bmsConfig.ssid) + "\">";
    page += "        <label for=\"password\">Password:</label>";
    page += "        <input type=\"password\" name=\"password\" value=\"" + String(bmsConfig.password) + "\">";
    page += "      </div>";
    
    page += "      <div class=\"form-group\">";
    page += "        <h2>MQTT Configuration</h2>";
    page += "        <label for=\"mqtt_server\">Server:</label>";
    page += "        <input type=\"text\" name=\"mqtt_server\" value=\"" + String(bmsConfig.mqtt_server) + "\">";
    page += "        <label for=\"mqtt_port\">Port:</label>";
    page += "        <input type=\"number\" name=\"mqtt_port\" value=\"" + String(bmsConfig.mqtt_port) + "\">";
    page += "        <label for=\"mqtt_topic\">Topic:</label>";
    page += "        <input type=\"text\" name=\"mqtt_topic\" value=\"" + String(bmsConfig.mqtt_topic) + "\">";
    page += "      </div>";
    
    page += "      <div class=\"form-group\">";
    page += "        <h2>Command</h2>";
    page += "        <label for=\"command\">Command:</label>";
    page += "        <input type=\"text\" name=\"command\" value=\"" + String(bmsConfig.command) + "\">";
    page += "      </div>";
    
    page += "      <button type=\"submit\">Save Configuration</button>";
    page += "    </form>";
    
    page += "    <div class=\"actions\">";
    page += "      <a href=\"/send\" class=\"action-btn\">Send Command</a>";
    page += "      <a href=\"/restart\" class=\"action-btn\">Restart Device</a>";
    page += "      <a href=\"/scan\" class=\"action-btn\">Scan Networks</a>";
    page += "      <a href=\"/reset_config\" class=\"action-btn\">Reset to Defaults</a>";
    page += "      <a href=\"/test_mqtt\" class=\"action-btn\">Test MQTT Connection</a>";
    page += "    </div>";
    page += "  </div>";
    page += "</div>";
    
    page += "<div class=\"status-info\">";
    page += "  <p>System Status: " + String(apModeActive ? String("AP Mode") : String("STA Mode")) + "</p>";
    page += "  <p>IP Address: " + String(apModeActive ? WiFi.softAPIP().toString() : WiFi.localIP().toString()) + "</p>";
    page += "</div>";
    
    page += "</body></html>";
    
    server.send(200, "text/html", page);
  });
  
  // 状态页面内容
  server.on("/status", []() {
    String page = "";
    
    page += "<div class=\"status-section\">";
    page += "  <h2>MQTT Status</h2>";
    page += "  <div class=\"status-item\">";
    page += "    <strong>Connection Status:</strong> ";
    page += "    <span class=\"" + String(mqttConnected ? "status-ok" : "status-error") + "\">"; 
    page += "      " + getMQTTStatusText() + "</span>";
    page += "  </div>";
    page += "  <div class=\"status-item\">";
    page += "    <strong>Server:</strong> " + String(bmsConfig.mqtt_server) + ":" + String(bmsConfig.mqtt_port) + "</div>";
    page += "  <div class=\"status-item\">";
    page += "    <strong>Topic:</strong> " + String(bmsConfig.mqtt_topic) + "</div>";
    page += "</div>";
    
    page += "<div class=\"status-section\" style=\"margin-top: 20px;\">";
    page += "  <h2>Debug Output</h2>";
    page += "  <div class=\"debug-output\">";
    
    // 只显示最近6条调试信息
    int displayedMessages = 0;
    for (int i = 0; i < DEBUG_BUFFER_SIZE && displayedMessages < 6; i++) {
        int index = (debugIndex + i) % DEBUG_BUFFER_SIZE;
        if (!debugMessages[index].isEmpty()) {
            page += "    <div class=\"debug-item\">";
            page += "      <div class=\"debug-timestamp\">[" + String(millis() / 1000) + "s]</div>";
            page += "      <div class=\"debug-message\">" + debugMessages[index] + "</div>";
            page += "    </div>";
            displayedMessages++;
        }
    }
    
    page += "  </div>";
    page += "</div>";
    
    // 去掉 Last Sent Command
    // 保留 Last Received Response
    page += "<div class=\"status-section\" style=\"margin-top: 20px;\">";
    page += "  <h2>MAX485 Communication</h2>";
    page += "  <div class=\"status-item\">";
    page += "    <strong>Last Received Response:</strong><br>";
    page += "    <pre style=\"background-color: #f8f8f8; padding: 10px; border: 1px solid #ddd;\">";
    page += lastReceivedResponse.isEmpty() ? "No response received yet" : lastReceivedResponse;
    page += "    </pre>";
    page += "  </div>";
    page += "</div>";
    
    page += "<script>";
    // 刷新频率改成20秒
    page += "function refreshStatus() {";
    page += "  document.getElementById('status-content').innerHTML = '<div style=\"text-align:center;\">Refreshing...</div>';";
    page += "  fetch('/status')";
    page += "    .then(response => response.text())";
    page += "    .then(data => {";
    page += "      document.getElementById('status-content').innerHTML = data;";
    page += "      setTimeout(refreshStatus, 20000);";
    page += "    })";
    page += "    .catch(error => {";
    page += "      document.getElementById('status-content').innerHTML = '<div class=\"status-error\">Failed to refresh status</div>';";
    page += "      setTimeout(refreshStatus, 20000);";
    page += "    });";
    page += "}";
    page += "document.addEventListener('DOMContentLoaded', function() {";
    page += "  openTab('status');";
    page += "  refreshStatus();";
    page += "})";
    page += "document.getElementById('last-update').textContent = '" + String(millis() / 1000) + "';";
    page += "</script>";
    
    server.send(200, "text/html", page);
  });
  
  // 保存配置
  server.on("/save", []() {
    if (server.hasArg("ssid")) strcpy(bmsConfig.ssid, server.arg("ssid").c_str());
    if (server.hasArg("password")) strcpy(bmsConfig.password, server.arg("password").c_str());
    if (server.hasArg("mqtt_server")) strcpy(bmsConfig.mqtt_server, server.arg("mqtt_server").c_str());
    if (server.hasArg("mqtt_port")) bmsConfig.mqtt_port = server.arg("mqtt_port").toInt();
    if (server.hasArg("mqtt_topic")) strcpy(bmsConfig.mqtt_topic, server.arg("mqtt_topic").c_str());
    if (server.hasArg("command")) strcpy(bmsConfig.command, server.arg("command").c_str());
    
    saveConfig();
    
    server.send(200, "text/plain", "Configuration saved! Connecting to WiFi...");
    
    if (connectWiFi()) {
      server.send(200, "text/plain", "WiFi connected! You can now access the web interface at: " + WiFi.localIP().toString());
      // 尝试连接MQTT
      connectMQTT();
    } else {
      server.send(200, "text/plain", "WiFi connection failed. AP mode activated. Connect to 'ESP8266 BMS Config' and access 192.168.4.1");
      startAP();
    }
  });
  
  // 发送命令
  server.on("/send", []() {
    String response = sendCommandAndWait(bmsConfig.command, SERIAL_READ_TIMEOUT);
    
    if (response.length() > 0) {
      Serial.print("Response: ");
      Serial.println(response);
      
      if (mqttConnected) {
        if (client.publish(bmsConfig.mqtt_topic, response.c_str())) {
          server.send(200, "text/plain", "Command sent and published to MQTT");
        } else {
          server.send(200, "text/plain", "Command sent but MQTT publish failed");
        }
      } else {
        server.send(200, "text/plain", "Command sent, but MQTT is not connected");
      }
    } else {
      server.send(200, "text/plain", "No response received");
    }
  });
  
  // 重启设备
  server.on("/restart", []() {
    server.send(200, "text/plain", "Restarting device...");
    delay(1000);
    ESP.restart();
  });
  
  // 扫描WiFi网络
  server.on("/scan", []() {
    String page = "<html><body><h1>WiFi Networks</h1><ul>";
    
    int n = WiFi.scanNetworks();
    if (n == 0) {
      page += "<li>No networks found</li>";
    } else {
      for (int i = 0; i < n; i++) {
        page += "<li>" + WiFi.SSID(i) + " (" + WiFi.RSSI(i) + " dBm)";
        page += (WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " Open</li>" : " Encrypted</li>";
      }
    }
    
    page += "</ul><a href=\"/\">Back</a></body></html>";
    server.send(200, "text/html", page);
  });
  
  // 重置配置
  server.on("/reset_config", []() {
    memset(&bmsConfig, 0, sizeof(BMSConfig));
    bmsConfig.configReady = 0;
    initEEPROM();
    
    server.send(200, "text/plain", "Configuration reset to defaults! Restarting...");
    delay(1000);
    ESP.restart();
  });
  
  // 测试MQTT连接
  server.on("/test_mqtt", []() {
    server.send(200, "text/plain", "Testing MQTT connection...");
    
    bool result = connectMQTT();
    
    if (result) {
      server.send(200, "text/plain", "MQTT connection successful!");
    } else {
      server.send(200, "text/plain", "MQTT connection failed. Check server settings and network connectivity.");
    }
  });
}

// MAX485控制函数
void setMax485ReceiveMode() {
  digitalWrite(MAX485_RE_DE, LOW);
}

void setMax485TransmitMode() {
  digitalWrite(MAX485_RE_DE, HIGH);
  delay(1);
}

String sendCommandAndWait(const char* cmd, unsigned int timeoutMs) {
  lastSentCommand = String(cmd);
  addDebugMessage("Sending command: " + lastSentCommand);
  
  setMax485TransmitMode();
  max485Serial.print(cmd);
  setMax485ReceiveMode();
  
  unsigned long startTime = millis();
  String response = "";
  
  while (millis() - startTime < timeoutMs) {
    if (max485Serial.available()) {
      response += (char)max485Serial.read();
    }
  }
  
  lastReceivedResponse = response;
  addDebugMessage("Received response: " + (response.isEmpty() ? "None" : response.substring(0, 50) + (response.length() > 50 ? "..." : "")));
  
  return response;
}

// OLED显示函数（全部英文）
void showLCD(String message, int lineIndex, bool mqttConnected) {
  display.clearDisplay();
  
  // 显示WiFi状态
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("[WiFi] ");
  if (WiFi.status() == WL_CONNECTED) {
    display.print(WiFi.localIP().toString());
  } else {
    display.print(apModeActive ? "AP Mode" : "Disconnected");
  }
  
  // 定义每行位置
  const int lineYPos[] = {22, 34, 46};
  
  if (lineIndex < 3 && message.length() > 0) {
    display.setCursor(0, lineYPos[lineIndex]);
    display.print(message);
  }
  
  // 显示时间和MQTT状态
  display.setCursor(0, 54);
  unsigned long currentTime = millis() / 1000;
  display.print("T: ");
  display.print(currentTime);
  display.print("s [mqtt] ");
  display.print(mqttConnected ? "OK" : "Off");
  
  display.display();
}

// MQTT回调函数
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  
  String message;
  for (unsigned int i = 0; i < length; i++) {
    message += (char)payload[i];
  }
  
  Serial.println(message);
  showLCD("MQTT Msg:", 0, true);
  showLCD(message.substring(0, 16), 1, true);
  if (message.length() > 16) {
    showLCD(message.substring(16, 32), 2, true);
  }
  
  addDebugMessage("MQTT message received on topic " + String(topic) + ": " + message.substring(0, 50) + (message.length() > 50 ? "..." : ""));
}

void setup() {
  Serial.begin(115200);
  Serial.println("\nSystem Initializing...");
  
  // 初始化随机数生成器
  randomSeed(millis());
  
  // 初始化硬件
  initEEPROM();
  
  // 初始化I2C和OLED
  Wire.begin(SDA_PIN, SCL_PIN);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 initialization failed"));
    while(true);
  }
  
  // 初始化MAX485
  pinMode(MAX485_RE_DE, OUTPUT);
  setMax485ReceiveMode();
  max485Serial.begin(9600);
  
  // 显示启动信息
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("System Starting...");
  display.display();
  delay(1000);
  
  // 设置MQTT回调
  client.setCallback(callback);
  
  // 初始化调试信息
  for (int i = 0; i < DEBUG_BUFFER_SIZE; i++) {
    debugMessages[i] = "";
  }
  addDebugMessage("System initialized");
  
  // 连接WiFi
  if (!connectWiFi()) {
    startAP();
  } else {
    // WiFi连接成功后，启动Web服务
    if (!serverStarted) {
      setupServerRoutes();
      server.begin();
      serverStarted = true;
      Serial.println("Web server started on port 80");
      showLCD("Web Server: 80", 2, true);
      addDebugMessage("Web server started");
    }
    
    // 然后尝试连接MQTT
    connectMQTT();
  }
  
  Serial.println("Setup completed");
  addDebugMessage("Setup completed");
}

void loop() {
  // 处理Web服务器请求
  server.handleClient();
  
  // 如果不在AP模式下，检查WiFi和MQTT连接
  if (!apModeActive) {
    // 检查WiFi连接
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("WiFi disconnected, reconnecting...");
      mqttConnected = false;
      showLCD("WiFi Lost", 0, false);
      addDebugMessage("WiFi disconnected, attempting to reconnect");
      if (!connectWiFi()) {
        startAP();
      }
    }
    
    // 检查MQTT连接
    if (!mqttConnected && (millis() - lastMQTTConnectAttempt > mqttReconnectInterval)) {
      Serial.println("MQTT disconnected, attempting reconnection...");
      addDebugMessage("MQTT disconnected, attempting reconnection");
      lastMQTTConnectAttempt = millis();
      connectMQTT();
    }
    
    // 如果MQTT已连接，处理MQTT消息
    if (mqttConnected) {
      client.loop();
    }
  }
  
  // 定时发送命令
  if (millis() - lastSendTime >= sendInterval) {
    String response = sendCommandAndWait(bmsConfig.command, SERIAL_READ_TIMEOUT);
    
    if (response.length() > 0) {
      Serial.print("Command sent, response: ");
      Serial.println(response);
      showLCD("Data Sent/Recv", 0, mqttConnected);
      addDebugMessage("Command sent successfully, response received");
      
      if (mqttConnected) {
        if (client.publish(bmsConfig.mqtt_topic, response.c_str())) {
          showLCD("MQTT Publish OK", 1, true);
          addDebugMessage("MQTT publish successful");
        } else {
          showLCD("MQTT Publish Fail", 1, false);
          mqttConnected = false; // 发布失败，标记为断开连接
          addDebugMessage("MQTT publish failed, state: " + String(client.state()));
        }
      }
    } else {
      Serial.println("Command sent, no response");
      showLCD("No Response", 0, mqttConnected);
      addDebugMessage("Command sent, but no response received");
    }
    
    lastSendTime = millis();
  }
}